package cn.xj.rf.amaplocation;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Location;
import android.util.Log;
import android.widget.Toast;

import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.apache.cordova.CordovaWebView;
import org.apache.cordova.LOG;
import org.apache.cordova.PermissionHelper;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;

/**
 * This class echoes a string called from JavaScript.
 */
public class AmapLocationPlugin extends CordovaPlugin {
    private String TAG = "AmapLocationPlugin";
    String[] permissions = {
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE
    };
    CallbackContext context;
    private String action;
    private JSONArray args;
    //声明AMapLocationClient类对象
    private AMapLocationClient mLocationClient = null;
    private AMapLocationClient onceLocationClient = null;
    private int _interval;
    boolean isBackgroundLocationRunning = false;
    AMapLocation lastLocation = null;


    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);
        //注册广播接收器
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("cn.xj.rf.AmapLocationPlugin");
        this.cordova.getActivity().registerReceiver(new LocationChangeReceiver(),intentFilter);

    }

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        //context = callbackContext;
        this.action = action;
        this.args = args;
        switch (action) {
            case "onceLocation":
                if (hasPermisssion()) {
                    this.onceLocation(callbackContext);
                } else {
                    context = callbackContext;
                    PermissionHelper.requestPermissions(this, 0, permissions);
                }
                break;
            case "startBackgroundLocation":
                if (hasPermisssion()) {
                    this.startBackgroundLocation(callbackContext);
                } else {
                    context = callbackContext;
                    PermissionHelper.requestPermissions(this, 0, permissions);
                }
                break;
            case "stopBackgroundLocation":
                this.stopBackgroundLocation(callbackContext);
                break;
            case "getLastLocation":
                if (null != lastLocation)
                    callbackContext.success(lastLocation.toJson(3));
                else
                    callbackContext.error("还未定位过");
                break;
            case "isBackgroundLocationRunning":
                callbackContext.success(isBackgroundLocationRunning ? 1 : 0);
                break;
            default:
                return false;
        }
        return true;
    }

    private void onceLocation(CallbackContext context) {
        Context activity = this.cordova.getActivity();
        if (onceLocationClient == null) {
            onceLocationClient = new AMapLocationClient(activity.getApplicationContext());
            AMapLocationClientOption mOption = new AMapLocationClientOption();
            //可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
            mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Device_Sensors);
            //mOption.setGpsFirst(true);//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
            mOption.setHttpTimeOut(30000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
            mOption.setNeedAddress(false);//可选，设置是否返回逆地理地址信息。默认是true
            mOption.setOnceLocation(true);//可选，设置是否单次定位。默认是false
            mOption.setOnceLocationLatest(true);//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
            AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTPS);//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
            mOption.setSensorEnable(true);//可选，设置是否使用传感器。默认是false
            mOption.setWifiScan(true); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
            mOption.setLocationCacheEnable(true); //可选，设置是否使用缓存定位，默认为true
            onceLocationClient.setLocationOption(mOption);
            onceLocationClient.setLocationListener(new AMapLocationListener() {
                @Override
                public void onLocationChanged(AMapLocation location) {
                    onceLocationClient.stopLocation();
                    if (null != location) {
                        JSONObject r = new JSONObject();
                        try {
                            r.put("latitude", location.getLatitude());
                            r.put("longitude", location.getLongitude());
                            r.put("accuracy", location.getAccuracy());
                            r.put("altitude", location.getAltitude());
                            r.put("speed", location.getSpeed());
                            r.put("provider", location.getProvider());
                            context.success(r);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    } else {
                        context.error("定位失败");
                    }
                }
            });
        }
        onceLocationClient.startLocation();
    }

    //开始后台连续定位
    private void startBackgroundLocation(CallbackContext callbackContext) throws JSONException {
        int interval = args.getInt(0);
        this._interval = interval;
        PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
        r.setKeepCallback(true);
        callbackContext.sendPluginResult(r);
        Context activity = this.cordova.getActivity();
        if (mLocationClient == null) {
            mLocationClient = new AMapLocationClient(activity.getApplicationContext());
            mLocationClient.setLocationOption(getDefaultOption());
            mLocationClient.setLocationListener(new AMapLocationListener() {
                @Override
                public void onLocationChanged(AMapLocation location) {
                    if (!isBackgroundLocationRunning)
                        isBackgroundLocationRunning = true;
                    if (null != location) {
                        lastLocation = location;
                        Intent intent = new Intent("cn.xj.rf.AmapLocationPlugin");
                        intent.putExtra("lastLocation",location);
                        activity.sendBroadcast(intent);
//                        Toast.makeText(activity,location.toJson(2).toString() ,Toast.LENGTH_SHORT).show();
//                        callbackContext.success(location.toJson(1));
                        PluginResult result = new PluginResult(PluginResult.Status.OK, location.toJson(1));
                        result.setKeepCallback(true);
                        callbackContext.sendPluginResult(result);
                    } else {
                        callbackContext.error("定位失败");
                    }
                }
            });
        }
        mLocationClient.startLocation();
//        context.success();

    }

    // 停止后台连续定位
    private void stopBackgroundLocation(CallbackContext context) {
        if (isBackgroundLocationRunning)
            isBackgroundLocationRunning = false;
        if (this.mLocationClient != null) {
            this.mLocationClient.stopLocation();
            this.mLocationClient = null;
            context.success();
        } else {
            context.error("未开始运行，无需结束");
        }

    }

    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(true);//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(this._interval * 1000);//可选，设置定位间隔。默认为2秒
        mOption.setNeedAddress(false);//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false);//可选，设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(false);//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(true);//可选，设置是否使用传感器。默认是false
        mOption.setWifiScan(true); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setLocationCacheEnable(true); //可选，设置是否使用缓存定位，默认为true
        return mOption;
    }

    public void onRequestPermissionResult(int requestCode, String[] permissions,
                                          int[] grantResults) throws JSONException {
        PluginResult result;
        //This is important if we're using Cordova without using Cordova, but we have the geolocation plugin installed
        if (context != null) {
            for (int r : grantResults) {
                if (r == PackageManager.PERMISSION_DENIED) {
                    LOG.d(TAG, "Permission Denied!");
                    result = new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION);
                    context.sendPluginResult(result);
                    return;
                }

            }
            this.execute(this.action, this.args, this.context);
        }
    }

    public boolean hasPermisssion() {
        for (String p : permissions) {
            if (!PermissionHelper.hasPermission(this, p)) {
                return false;
            }
        }
        return true;
    }

    class LocationChangeReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            AMapLocation  lastLocation = intent.getParcelableExtra("lastLocation");
            Log.d(TAG, "onReceive: " );
        }
    }
}
